var PageSelect = function () {
  var template = /* html */ `
    <el-select class="page-select" :popper-class="pageSelectPopperClass" v-model="selectValue" :value-key="valueKey" :loading="loading" :filterable="filterable" :clearable="clearable"
      :size="size" :disabled="disabled" :placeholder="placeholder" :filter-method="filterSelectMethod" @change="selectChange" @visible-change="visibleChange">
      <div ref="pageSelectDropdown" class="page-select-dropdown" :class="{'has-page':totalPage>1}">
        <el-option v-if="selectOption!==null" style="display:none" :value="selectOption.value" :label="selectOption.label"></el-option>
        <slot :options="dropdownOptions">
          <template v-for="option in dropdownOptions">
            <template v-if="optionType!=='object'">
              <el-option :key="'option_'+option" :value="option"></el-option>
            </template>
            <template v-else-if="valueKey">
              <el-option :key="'option_'+option[valueKey]" :value="option" :label="option[labelField]"></el-option>
            </template>
            <template v-else>
              <el-option :key="'option_'+option[valueField]" :value="option[valueField]" :label="option[labelField]"></el-option>
            </template>
          </template>
        </slot>
      </div>

      <div class="page-select-pagination clearfix" v-if="totalPage>1">
        <div v-if="currentPage>1" style="float:left" @click="pageChange('previous')">上一页</div>
        <div v-if="currentPage<totalPage" style="float:right" @click="pageChange('next')">下一页</div>
      </div>
    </el-select>
  `;

  return {
    props: {
      value: {
        type: [Number, Object, String],
        required: true
      },
      options: {
        type: Array,
        default: function () {
          return [];
        }
      },
      valueKey: String,
      loading: Boolean,
      disabled: Boolean,
      filterable: Boolean,
      filterMethod: Function,
      clearable: Boolean,
      placeholder: String,
      size: String,
      valueField: {
        type: String,
        default: 'value'
      },
      labelField: {
        type: String,
        default: 'label'
      },
      pageSize: {
        type: Number,
        default: 100
      },
      hasNullOption: {
        type: Boolean,
        default: false
      },
      popperClass: String
    },

    watch: {
      value: function () {
        if (this.inputValue !== null) {
          this.inputValue = null;
          return;
        }
        this.selectValue = this.value;
      },
      options: function () {
        this.filterOptions = this.options;
        if (this.visibleStatus) {
          this.toSelectItem();
        }
      },
      pageOption: function (newObj) {
        if (this.hasNullOption && SysUtil.isEmpty(newObj)) {
          if (this.selectValue !== '') {
            return;
          }
        }
        this.selectOption = newObj;
      }
    },

    computed: {
      pageSelectPopperClass: function () {
        var popperClass = this.popperClass;
        if (SysUtil.isEmpty(popperClass)) {
          popperClass = 'page-select-popper';
        } else {
          popperClass = `page-select-popper ${popperClass}`;
        }
        return popperClass;
      },
      totalPage: function () {
        var filterOptions = this.filterOptions;
        var pageSize = this.pageSize;
        var count = filterOptions.length / pageSize;
        count = Math.ceil(_.round(count, 2));
        return count;
      },
      optionType: function () {
        var options = this.options;
        if (options.length === 0) {
          return null;
        }
        return typeof options[0];
      },
      dropdownOptions: function () {
        var filterOptions = this.filterOptions;
        if (SysUtil.isEmpty(filterOptions)) {
          return [];
        }
        var currentPage = this.currentPage;
        var pageSize = this.pageSize;
        var startIndex = (currentPage - 1) * pageSize;
        filterOptions = filterOptions.slice(startIndex, startIndex + pageSize);
        return filterOptions;
      },
      pageOption: function () {
        var selectValue = this.selectValue;
        if (this.dropdownOptions.length === 0 || selectValue === '') {
          return null;
        }

        if (this.optionType !== 'object') {
          return {
            value: selectValue,
            label: selectValue
          };
        }

        var options = this.options;
        var label = null;
        var valueKey = this.valueKey;
        var labelField = this.labelField;
        if (valueKey) {
          obj = _.find(options, function (o) {
            return o[valueKey] === selectValue[valueKey];
          });
          if (obj !== undefined) {
            label = obj[labelField];
          }
          if (label === null) {
            return null;
          }
          return {
            value: obj,
            label: label
          };
        }

        var valueField = this.valueField;
        obj = _.find(options, function (o) {
          return o[valueField] === selectValue;
        });
        if (obj !== undefined) {
          label = obj[labelField];
        }
        if (label === null) {
          return null;
        }
        return {
          value: selectValue,
          label: label
        };
      }
    },

    data: function () {
      return {
        selectValue: this.value,
        inputValue: null,
        filterOptions: this.options,
        currentPage: 1,
        selectOption: null,
        visibleStatus: false
      };
    },

    methods: {
      selectChange: function () {
        var selectValue = this.selectValue;
        this.inputValue = selectValue;
        this.$emit('input', selectValue);
        this.$emit('change', selectValue);
      },

      pageChange: function (type) {
        var currentPage = this.currentPage;
        if (type === 'previous') {
          currentPage--;
        } else if (type === 'next') {
          currentPage++;
        }
        this.currentPage = currentPage;

        var self = this;
        this.$nextTick(function () {
          if (self.$refs['pageSelectDropdown']) {
            $(self.$refs['pageSelectDropdown']).scrollTop(0);
          }
        });
      },

      filterSelectMethod: function (value) {
        var options = this.options;
        var filterMethod = this.filterMethod;
        if (filterMethod !== undefined) {
          options = filterMethod(options, value);
        } else {
          if (value !== '') {
            var self = this;
            value = value.toLowerCase();
            options = _.filter(options, function (option) {
              if (self.optionType !== 'object') {
                return option.toLowerCase().indexOf(value) !== -1;
              }

              var optionValue = option[self.labelField];
              if (SysUtil.isEmpty(optionValue)) {
                return false;
              }
              return optionValue.toLowerCase().indexOf(value) !== -1;
            });
          }
        }

        this.currentPage = 1;
        this.filterOptions = options;
      },

      visibleChange: function (visible) {
        if (visible) {
          this.filterOptions = this.options;
          this.toSelectItem();
        }
        this.visibleStatus = this.visible;
        this.$emit('visible-change', visible);
      },

      toSelectItem: function () {
        var selectValue = this.selectValue;
        if (selectValue === '') {
          return;
        }

        var filterOptions = this.filterOptions;
        var index;
        var valueKey = this.valueKey;
        var valueField = this.valueField;
        if (this.optionType !== 'object') {
          index = _.findIndex(filterOptions, function (value) {
            return value === selectValue;
          });
        } else if (valueKey) {
          index = _.findIndex(filterOptions, function (obj) {
            return obj[valueKey] === selectValue[valueKey];
          });
        } else {
          index = _.findIndex(filterOptions, function (obj) {
            return obj[valueField] === selectValue;
          });
        }

        var currentPage;
        if (index <= 0) {
          currentPage = 1;
        } else {
          currentPage = Math.ceil((index + 1) / this.pageSize);
        }
        this.currentPage = currentPage;

        var self = this;
        this.$nextTick(function () {
          var dropdownDom = self.$refs['pageSelectDropdown'];
          if (dropdownDom === undefined) {
            return;
          }

          var domIndex = index % this.pageSize;
          $(dropdownDom).scrollTop(domIndex * 34);
        });
      }
    },

    template: template
  };
}();
